package com.songyang.yougnsql.core.data.page;

import com.songyang.yougnsql.core.utils.RandomUtil;

import java.util.Arrays;

/**
 * @ClassName PageOne
 * @Description 页面的第一位
 * db启动时给100~107字节处填入一个随机字节，db关闭时将其拷贝到108~115字节
 * 数据库在每次启动时就会检查第一页的两处的字节是否相同一次来判断是否是正常关闭
 * @date 2022/12/5 13:33
 * @Author yanceysong
 * @Version 1.0
 */
public class PageOne {
    public static final int PAGE_ONE_NUMBER = 1;
    /**
     * 校验位的起始偏移量
     */
    private static final short OF_VC = 100;
    /**
     * 校验位的长度
     */
    private static final short LEN_VC = 8;

    /**
     * 初始化数据信息
     *
     * @return 第一页的数据信息
     */
    public static byte[] initRaw() {
        byte[] raw = new byte[Page.PAGE_SIZE];
        setVcOpen(raw);
        return raw;
    }

    /**
     * 数据库开启的时候向页面写入校验信息
     *
     * @param raw 第一页的字节数组
     */
    private static void setVcOpen(byte[] raw) {
        System.arraycopy(RandomUtil.randomBytes(LEN_VC), 0, raw, OF_VC, LEN_VC);
    }

    /**
     * 向页面写入校验信息
     *
     * @param page 页面
     */
    public static void setVcOpen(Page page) {
        page.setDirty(true);
        setVcOpen(page.getData());
    }

    /**
     * 数据库关闭的时候写入校验信息
     *
     * @param page 第一页
     */
    public static void setVcClose(Page page) {
        page.setDirty(true);
        setVcClose(page.getData());
    }

    /**
     * 数据库关闭的时候写入校验信息
     *
     * @param raw 第一页的数据
     */
    private static void setVcClose(byte[] raw) {
        System.arraycopy(raw, OF_VC, raw, OF_VC + LEN_VC, LEN_VC);
    }

    /**
     * 校验数据库是否正常关闭
     *
     * @param raw 页面的数据信息
     * @return 是否正常关闭
     */
    public static Boolean checkVc(byte[] raw) {
        return Arrays.equals(Arrays.copyOfRange(raw, OF_VC, OF_VC + LEN_VC)
                , Arrays.copyOfRange(raw, OF_VC + LEN_VC, OF_VC + 2 * LEN_VC));
    }

    /**
     * 校验数据库是否正常关闭
     *
     * @param page 第一页
     * @return 是否正常关闭
     */
    public static Boolean checkVc(Page page) {
        page.release();
        return checkVc(page.getData());
    }
}
